package cn.fangline.wo.task.akka.actors;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import cn.fangline.base.util.Constants;
import cn.fangline.base.util.StringUtil;
import cn.fangline.base.util.exception.WrongContainException;
import cn.fangline.wo.model.Agent;
import cn.fangline.wo.task.akka.messages.AgentPage;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.apache.log4j.Logger;
import org.jsoup.HttpStatusException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketTimeoutException;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * Created by 抽离 on 2017/6/20 0020.
 */


public class AgentActor extends AbstractActor {
    private String userAgent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50";

    private final static Logger logger = Logger.getLogger(AgentActor.class);
//    private ActorRef houseActor;
//
//    public AgentActor(ActorRef houseActor) {
//        this.houseActor = houseActor;
//    }


    private ActorRef agentMergerRef;

    public AgentActor(ActorRef agentMergerRef) {
        this.agentMergerRef = agentMergerRef;
    }

    public Receive createReceive() {
        return
                receiveBuilder()
                        .match(AgentPage.class, this::onRecevieMsg)
                .build();
    }


    private void onRecevieMsg(AgentPage agentPage) {
//        System.out.println("进入agenActor");
        if(agentPage.getCount() < 0){
            return;
        }
//        System.out.println("入口url：" + agentPage);
        try {
            Document doc= Jsoup.connect(agentPage.getUrl())
                    .userAgent(userAgent)
                    .proxy(new Proxy(Proxy.Type.HTTP
                            , new InetSocketAddress("proxy.abuyun.com", 9010)))
                    .header("Proxy-Authorization", "Basic SE80MDNUNzI3V1QwOThXUDozQzRBOTUxM0RCQ0EyQUZG")
                    .header("Proxy-Switch-Ip", "yes")
                    .timeout(5*1000)
                    .get();
//            System.out.println("agentDoc：" + doc);
            Element verify = doc.getElementById("verify_page");
            if(verify!=null){
                throw new WrongContainException("请求频繁页面，重试:"+ agentPage.getCount());
            }
            Elements agents = doc.getElementsByClass("jjr-itemmod");
            String noSearch = doc.select("p.msg").text();
            if(!StringUtil.isEmpty(noSearch)){
                System.out.println("----------=" + noSearch  + "-----------");
                System.out.println("---no search page---");
                return;
            }
            if(StringUtil.isEmpty(agents.toString())){
                System.out.println("----------=" + "出错重试"  + "-----------");
                throw new WrongContainException("爬取出错");
            }
            for (Element element : agents) {
                Agent agent = new Agent();
                agent.setCreateTime(new Date());
                agent.setNet(Constants.ANJUKE);
                agent.setCityId(agentPage.getCityId());
                String agentUrl = element.select("a").attr("href").replaceAll("[   ]","").trim();
                agent.setUrl(agentUrl);
                agent.setOriginUserId(agentUrl.replaceAll("http://.*\\.anjuke\\.com/","").replaceAll("[   ]","").trim()
                );
                agent.setAgentName(element.select("a").attr("title").replaceAll("[   ]","").trim());//姓名
                agent.setAvatarUrl(element.select("a img").attr("src").replaceAll("[   ]","").trim());//头像
                agent.setCorp(element.select(".jjr-info .mg-top a").first().text().replaceAll("[   ]","").trim());//公司
                agent.setDept(element.select(".jjr-info .jjr-desc a").eq(1).text().replaceAll("[   ]","").trim());//公司分部
                agent.setTel(element.select(".jjr-side").text().replaceAll("[   ]","").trim());//电话
                agent.setSection(element.select(".jjr-info .xq_tag a").text().replaceAll("[   ]","").trim());//主营小区
                try{
                    Agent newAgent = new Agent();
                    newAgent = newAgent.selectOne(new EntityWrapper<Agent>().eq("origin_user_id", agent.getOriginUserId()));
                    if(newAgent != null){
                        agent = newAgent;
                    }else {
                        agent.insert();
                    }
//                    System.out.println("经纪人：" + agent);
                }catch(Exception e){
                    e.printStackTrace();
                    System.out.println("insert exception");
                }
                agentMergerRef.tell(agent, getSelf());//通知合并
            }
            Elements nextElements = doc.select(".aNxt");
            String next = null;
            if(nextElements != null && StringUtil.isNotEmpty(nextElements.toString())) {
                next = nextElements.get(0).attr("href");
                AgentPage nextAgentPage = new AgentPage();
                nextAgentPage.setUrl(next);
                nextAgentPage.setCityId(agentPage.getCityId());
                nextAgentPage.setCount(Constants.RETRY_COUNT);
                getSender().tell(nextAgentPage, getSelf());
            } else{//没有下一页了，通知关闭
//                getContext().system().terminate();
                System.out.println("经纪人爬取完成" + LocalDateTime.now());
//                getSender().tell(true, getSelf());
            }
        }catch (IOException | WrongContainException e){
//            System.out.println("AgentActor出现错误：" + e + "url：" + agentPage.getUrl());
            getSender().tell(agentPage, getSelf());
        }
        catch (Exception e) {
            agentPage.setCount(agentPage.getCount() - 1);
//            System.out.println("抓取出错重试：" + agentPage);
            logger.error("经纪人爬取出错：" + e + "url：" + agentPage.getUrl());//位置错误，记录
            getSender().tell(agentPage, getSelf());
            e.printStackTrace();
        }
    }
}
